/* ----------------------------------------------------------------------
 *	Shadow Quest
 *	Copyright (C) 2009 Prageeth Silva <prageeth@thenewcoders.com>
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *  ----------------------------------------------------------------------
 */

package map;

import org.newdawn.slick.Animation;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.SpriteSheet;

/** The lighting class, used for weather generation.
 *
 */
public class Lightning {

	private static int WIDTH = 120, HEIGHT = 330, FRAME_INTERVAL = 100, OFFSET_Y = 300, STRIKE_FRAME = 3;
	
	public static int STRIKE_DAMAGE = 30, STRIKE_RANGE = 100;
	
	private Animation disp;
	private boolean strike, over, active, allowed;
	private float x, y;
	
	/** Creates a new lighting object
	 * @param path The image path
	 * @throws SlickException
	 */
	public Lightning(Image image) 
	throws SlickException 
	{
		this.setDisplayAnimation(image);		
		this.reset();
	}
	
	/** Reset the lighting object values, but does not load the image again
	 * 
	 */
	public void reset() {
		this.setOver(false);
		this.setStrikeHappened(false);	
		this.setActive(false);
		this.setAllowed(false);
	}
	
	/** Update the lighting bolt
	 * @param world The reference to the world in which the lighting bolt exists.
	 * @param delta The time elapsed in milliseconds.
	 */
	public void update(World world, int delta) {
		
		if (this.isActive()) {
			this.getDisplayAnimation().update(delta);
			if (this.getDisplayAnimation().isStopped()) {
				this.setActive(false);
			} else {
				if (!this.isStrikeHappened() && this.getDisplayAnimation().getFrame() == STRIKE_FRAME) {
					this.setStrikeHappened(true);
					int duration =  this.getDisplayAnimation().getDuration(0)* this.getDisplayAnimation().getFrameCount();
					world.attackUnitsOnGround(this.getX(), this.getY(), STRIKE_RANGE, STRIKE_DAMAGE, duration);
				}
			}
		}
		
	}
	
	/** Render the entire screen, so it reflects the current game state.
     * @param g The Slick graphics object, used for drawing.
     * @param cameraOffsetX The number of pixels the world has been offset to in the x-direction (pixels).
     * @param cameraOffsetY The number of pixels the world has been offset to in the x-direction (pixels).
     */
    public void render(Graphics g, float cameraOffsetX, float cameraOffsetY)
    {
    	
    	if (this.isActive()) {
	    	this.getDisplayAnimation().draw((float)(this.getX()-cameraOffsetX-this.getWidth()/2),(float)(this.getY()-cameraOffsetY-OFFSET_Y));
    	}
    	
    }

    /** Make the lighting strike at a given point
     * @param x The x-coordinate of the point in the world
     * @param y The y-coordinate of the point in the world
     */
	public void strike(float x, float y) {
		this.moveTo(x, y);
		this.setActive(true);
		this.setAllowed(false);
		this.getDisplayAnimation().restart();
	}
	
	private Animation getDisplayAnimation() {
		return disp;
	}

	private void setDisplayAnimation(Image img) {
		this.disp = new Animation(new SpriteSheet(img,WIDTH,HEIGHT),FRAME_INTERVAL);
		this.disp.setLooping(false);
		this.disp.setAutoUpdate(false);
	}
	
	public float getWidth() {
		return WIDTH;
	}
	
	public float getHeight() {
		return HEIGHT;
	}

	public boolean isStrikeHappened() {
		return strike;
	}

	private void setStrikeHappened(boolean strike) {
		this.strike = strike;
	}
	
	public boolean isOver() {
		return over;
	}

	private void setOver(boolean over) {
		this.over = over;
	}

	public boolean isActive() {
		return active;
	}

	private void setActive(boolean active) {
		this.active = active;
	}
	
	private float getX() {
		return this.x;
	}

	private void setX(float x) {
		this.x = x;
	}

	private float getY() {
		return this.y;
	}

	private void setY(float y) {
		this.y = y;
	}
	
	/** Move the object to a point, but does NOT check for collision detection.
     * @param x The X coordinate (pixels).
     * @param y The Y coordinate (pixels).
     */
    public void moveTo(float x, float y) {
		this.setX(x);
		this.setY(y);
	}

	public boolean isAllowedStrike() {
		return this.allowed;
	}

	private void setAllowed(boolean allowed) {
		this.allowed = allowed;
	}
    
	public void allowStrike() {
    	this.setAllowed(true);
    }
    
}
